#include "string.h"

struct string_t *init_string(const unsigned char *str, int len)
{
    struct string_t *ret;
    // allocate appropriate memory space
    ret = (struct string_t *)malloc(sizeof(struct string_t));
    ret->data = (unsigned char *)malloc(sizeof(unsigned char) * len + 1);
    ret->len = len;

    if (str == NULL)
        memset(ret->data, 0, len); // if str is null, fill all 0
    else
        memcpy(ret->data, str, len); // if not , copy string to ret

    return ret;
}

struct string_t *sub_string(struct string_t *source, int pos, int len)
{
    struct string_t *ret;
    ret = init_string(NULL, len);
    // copy len char from data+pos;
    memcpy(ret->data, source->data + pos, len);

    return ret;
}

bool compare_string(struct string_t *first, struct string_t *second)
{
    int min_len = MIN(first->len, second->len);
    // if the lengths of the two are not equal, naturally not queal
    if (first->len != second->len)
        return false;

    // compare one by one in for loop+
    for (int i = 0; i < min_len; i++)
    {
        // if one of them (ch) is not equal, return false
        if (first->data[i] != second->data[i])
            return false;
    }

    return true;
}

// brute-force-match algorithm implementation on string_t
int find_string(struct string_t *source, struct string_t *pattern)
{
    if (source->len < pattern->len ||            // the substring length is longer than pattern
        (source->len == 0 || pattern->len == 0)) // one of them is empty
        return -1;                               // then return false

    // the traversal range is [0 ,len(master) - len(pattern)],
    // there is no need to match the len(pattern) end of master,reducing unnecessary traversal
    for (int source_index = 0; source_index < source->len - pattern->len; source_index++)
    {
        int pattern_index;

        for (pattern_index = 0; pattern_index < pattern->len; pattern_index++)
        {
            if (source->data[source_index + pattern_index] != pattern->data[pattern_index])
                break;
        } // end point of pattern string traversal

        // check the pattern_index value,if the values of pattern_index & patter->len are equal, it means that the pattern
        // string is matched from begining to end,then return the position from source string
        if (pattern_index == pattern->len)
            return source_index;

    } // end point of source string traversal

    // returning -1 indicates a failed match
    return -1;
}

int brute_force_match_algo(struct string_t *source, struct string_t *pattern)
{
    int source_pointer = 0, pattern_pointer = 0;
    while (source_pointer <= source->len && pattern_pointer <= pattern->len)
    {

        // if match
        if (source->data[source_pointer] == pattern->data[pattern_pointer])
        {
            source_pointer++;
            pattern_pointer++;
        }
        else
        {
            source_pointer = source_pointer - pattern_pointer + 1;
            pattern_pointer = 0;
        }
    }

    if (pattern_pointer >= pattern->len)
    {
        return source_pointer;
    }
}

void print_string(struct string_t *source)
{
    if (source) // if source is not empty , then print it out
        printf("@<string_t> { data: %s, len: %d }\n", source->data, source->len);
    else // if empty ,print nil flag
        printf("@<string_t> { data: (nil), len: -1 }\n");
}